<?php

namespace Addons\OaSystem\Controller;
use Think\ManageBaseController;

class OaApplicationController extends OaBaseController
{
    protected $model;
    protected $applyItemTypeStr;
    protected $subTypeStr;
    protected $meetingTrainTypes;

    function _initialize()
    {
        $this->model = $this->getModel('oa_application');
        $this->subTypeStr = array('差旅报销', '会议报销', '其他报销');
        $tripItemStr = array('交通费', '住宿费', '培训费', '其他', '伙食补助费', '市内交通费', '备注费用');
        $meetingItemStr = array('住宿费', '伙食费', '场地费', '授课费', '其他费用', '备注费用');
        $otherItemStr = array('其它');
        $this->meetingTrainTypes = array('一类', '二类', '三类');

        $this->applyItemTypeStr[0] =  $tripItemStr;
        $this->applyItemTypeStr[1] =  $meetingItemStr;
        $this->applyItemTypeStr[2] =  $otherItemStr;

        parent::_initialize();
//        $controller = strtolower(CONTROLLER_NAME);
//        $action = strtolower(ACTION_NAME);
//
//        $res ['title'] = '报销审批';
//        $res ['url'] = addons_url('OaSystem://OaApplication/lists', array('mdm' => I('mdm')));
//        $res ['class'] = $action == 'lists' ? 'cur' : '';
//        $nav [] = $res;
//        $this->assign('nav', $nav);
//        $res ['title'] = '个人报销申请';
//        $sub_nav[] = $res;
//
//        $res ['title'] = '待领取的任务';
//        $res ['url'] = addons_url('OaSystem://OaApplication/pendinglists', array('mdm' => I('mdm')));
//        $res ['class'] = $action == 'pendinglists' ? 'cur' : '';
//        $sub_nav[] = $res;
//        $res ['title'] = '已领走的任务';
//        $res ['url'] = addons_url('OaSystem://OaApplication/takelists', array('mdm' => I('mdm')));
//        $res ['class'] = $action == 'takelists' ? 'cur' : '';
//        $sub_nav[] = $res;
//        $res ['title'] = '处理过的任务';
//        $res ['url'] = addons_url('OaSystem://OaApplication/donelists', array('mdm' => I('mdm')));
//        $res ['class'] = $action == 'donelists' ? 'cur' : '';
//        $sub_nav[] = $res;
//        $res ['title'] = '报销申请单管理';
//        $res ['url'] = addons_url('OaSystem://OaApplication/applicationManage', array('mdm' => I('mdm')));
//        $res ['class'] = $action == 'applicationmanage' ? 'cur' : '';
//
//        $sub_nav[] = $res;
//        $this->assign('sub_nav', $sub_nav);

    }

    public function lists(){
        $p = empty(I('p')) ? 1 : I('p');
        $row = 20;
        $map['applyer'] = $this->cur_emp_id;
        $map['type'] = 3;
        $map['is_del'] = array('neq', 1);
        $len = D('OaApplicationView')->where($map)->count();
        $applies = D('OaApplicationView')->where($map)->order('submit_date desc')->page($p,$row)->select();
        for ($i=0; $i<count($applies); $i++) {
            $applies[$i]['submit_date'] = date('Y-m-d H:i:s',$applies[$i]['submit_date']);
            $applies[$i]['type_name'] = $this->subTypeStr[$applies[$i]['subtype']];
            $applies[$i]['show_state'] = $this->getApplicationProgressState($applies[$i]['id']);
            $applies[$i]['show_state_color'] = ($applies[$i]['show_state'] == '驳回') ? 'red' : '';
            if($applies[$i]['step'] == 1)
                $applies[$i]['redirect_url'] = U('add', array('type'=>$applies[$i]['type'],'subtype'=>$applies[$i]['subtype'],'application_id'=>$applies[$i]['id']));
            else
                $applies[$i]['redirect_url'] = U('details', array('type'=>$applies[$i]['type'],'subtype'=>$applies[$i]['subtype'],'application_id'=>$applies[$i]['id']));
        }
        if ($len > $row) {
            $page = new \Think\Page ( $len, $row );
            $page->setConfig ( 'theme', '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END% %HEADER%' );
            $list_data['_page'] = $page->show ();
        }
        $this->assign('_page',$list_data['_page']);
        $this->assign('applies',$applies);
        $this->display();
    }

    public function pendinglists(){

        $applies = getMyApprovalBufferPool($this->cur_emp_id);

        $p = empty(I('p')) ? 1 : I('p');
        $row = 20;
        $len = count($applies);
        for ($i=0; $i<count($applies); $i++) {
            $applies[$i]['submit_date'] = date('Y-m-d H:i:s',$applies[$i]['submit_date']);
            $applies[$i]['type_name'] = $this->subTypeStr[$applies[$i]['subtype']];
            $applies[$i]['show_state'] = $this->getApplicationProgressState($applies[$i]['id']);
            $applies[$i]['last_step'] = $this->isApplicationLastStep($applies[$i]['id']);
        }
        if ($len > $row) {
            $page = new \Think\Page ( $len, $row );
            $page->setConfig ( 'theme', '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END% %HEADER%' );
            $list_data ['_page'] = $page->show ();
        }
        $this->assign('_page',$list_data ['_page']);
        $this->assign('applies',$applies);
        $this->display();
    }

    public function takelists(){

        $p = empty(I('p')) ? 1 : I('p');
        $row = 20;
        $map['approver'] = $this->cur_emp_id;
        $map['is_del'] = array('neq', 1);
        $map['step'] = array('neq', 1);
        $map['type'] = 3;
        $map['status'] = array('neq', 1);
        $len = D('OaApplicationView')->where($map)->count();
        $applies = D('OaApplicationView')->where($map)->order('submit_date desc')->page($p,$row)->select();
        for ($i=0; $i<count($applies); $i++) {
            $applies[$i]['submit_date'] = date('Y-m-d H:i:s',$applies[$i]['submit_date']);
            $applies[$i]['type_name'] = $this->subTypeStr[$applies[$i]['subtype']];
            $applies[$i]['show_state'] = $this->getApplicationProgressState($applies[$i]['id']);
            $applies[$i]['last_step'] = $this->isApplicationLastStep($applies[$i]['id']);
        }
        if ($len > $row) {
            $page = new \Think\Page ( $len, $row );
            $page->setConfig ( 'theme', '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END% %HEADER%' );
            $list_data ['_page'] = $page->show ();
        }
        $this->assign('_page',$list_data ['_page']);
        $this->assign('applies',$applies);
        $this->display();
    }

    public function donelists(){

        $log_map['approver'] = $this->cur_emp_id;
        $log_map['step'] = array('gt', 1);
        $processLogApplyIds = db_select('OaProcessLog', $log_map, 'time desc', 'application_id');
        $processLogApplyIds = array_column($processLogApplyIds, 'application_id');
        $processLogApplyIds = array_unique($processLogApplyIds);

        $p = empty(I('p')) ? 1 : I('p');
        $row = 20;
        $map['is_del'] = array('neq', 1);
        $map['type'] = 3;
        $map['id'] = array('in',$processLogApplyIds);
        $len = D('OaApplicationView')->where($map)->count();
        $applies = D('OaApplicationView')->where($map)->order('submit_date desc')->page($p,$row)->select();
        for ($i=0; $i<count($applies); $i++) {
            $applies[$i]['submit_date'] = date('Y-m-d H:i:s',$applies[$i]['submit_date']);
            $applyType = db_find('oa_apply_type', ['id'=>$applies[$i]['type']]);
            $applies[$i]['type_name'] = $this->subTypeStr[$applies[$i]['subtype']];
            $applies[$i]['show_state'] = $this->getApplicationProgressState($applies[$i]['id']);
            $applies[$i]['show_state_color'] = ($applies[$i]['show_state'] == '驳回') ? 'red' : '';
            $applies[$i]['last_step'] = $this->isApplicationLastStep($applies[$i]['id']);
        }
        if ($len > $row) {
            $page = new \Think\Page ( $len, $row );
            $page->setConfig ( 'theme', '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END% %HEADER%' );
            $list_data ['_page'] = $page->show ();
        }
        $this->assign('_page',$list_data ['_page']);
        $this->assign('applies',$applies);
        $this->display();
    }

    public function leavelists() {
        parent::lists();
    }

    public function loglists() {
        $application_id = $_GET['application_id'];
        $prev_method = $_GET['method'];

        $logs = db_select('oa_process_log', ['application_id'=>$application_id], 'hop desc');
        foreach ($logs as $i => $log) {
            $approver = db_find('oa_employee', ['id'=>$log['approver']]);
            $logs[$i]['approver'] = $approver['name'];
            $logs[$i]['time'] = date('Y-m-d H:i:s', $logs[$i]['time']);
            $logs[$i]['result'] = ($logs[$i]['result']==0) ?'驳回':(($logs[$i]['step']==1)?'提交':'通过');
            $logs[$i]['font_color'] = ($logs[$i]['result']=='驳回') ? 'red' : '';
        }
        $application = D(OaApplicationView)->where(['id'=>$application_id])->find();
        $prev_url = U($prev_method, array('application_id'=>$application_id, 'type'=>$application['type'], 'subtype'=>$application['subtype']));
        $this->assign('application',$application);
        $this->assign('apply_logs',$logs);
        $this->assign('prev_url',$prev_url);
        $this->display();
    }

    public function add() {
        if(($userInfo = $this->getCurUserInfo()) == false) {
            $this->error(__METHOD__.'['.__LINE__.']'.'查找该用户员工信息失败！');
            return false;
        }
        if(IS_POST) {
            $application_id = $_POST['application_id'];
            $subtype = $_POST['subtype'];
            $itemtype = $_POST['itemType'];
            $button = $_POST['button'];
            if(!empty($_POST['button_add'])) {
                $button = '添加明细';
                $itinerary_id = $_POST['button_add'];
                $itemtype = $_POST['itemType'.$itinerary_id];
            }

            $content = array(
                'itemType' => $itemtype,
                'itemTypes' => $this->applyItemTypeStr[$subtype],
                'start' => $_POST['start_date'],
                'end' => $_POST['end_date'],
                'src' => explode('-', $_POST['start_addr']),
                'dst' => explode('-', $_POST['end_addr']),
                'costCenter' => $_POST['costCenter'],
                'project' => $_POST['project']
            );

            if($subtype == 0) {
                $content['itinerary'] = array();
                for($i = 1; $i < 10; $i++) {
                    if(empty($_POST['start_date'.$i]))
                        break;
                    $itinerary['id'] = $i-1;
                    $itinerary['start'] = $_POST['start_date'.$i];
                    $itinerary['end'] = $_POST['end_date'.$i];
                    $itinerary['src'] = explode('-', $_POST['start_addr'.$i]);
                    $itinerary['dst'] = explode('-', $_POST['end_addr'.$i]);
                    $itinerary['days'] = ((strtotime($itinerary['end'])-strtotime($itinerary['start']))/3600/24)+(($itinerary['start']==end($content['itinerary'])['end'])?0:1);
                    $itinerary['people_num'] = intval($_POST['people_num'.$i]);
                    array_push($content['itinerary'], $itinerary);
                }
                if($button == '新增行程') {
                    $new['id'] = empty($_POST['start_date1'])?0:($itinerary['id']+1);
                    if(!empty($itinerary['end'])) {
                        $new['start'] = date("Y-m-d",strtotime("+1 day",strtotime($itinerary['end'])));
                        $new['end'] = $new['start'];
                    }
                    if(!empty($itinerary['dst']))
                        $new['src'] = $itinerary['dst'];
                    $new['people_num'] = 1;
                    array_push($content['itinerary'], $new);
                }
                if($button == '删除行程') {
                    array_pop($content['itinerary']);
                    $map['application_id'] = $application_id;
                    $map['itinerary_id'] = $itinerary['id'];
                    M('oa_apply_item')->where($map)->delete();
                }
            }
            if($subtype == 1) {
                if(!empty($_POST['traintype']))
                    $content['trainType'] = $_POST['traintype']-1;
                $content['trainTypes'] = $this->meetingTrainTypes;
                $content['attendance'] = $_POST['attendance'];
            }

            if($button == '返回') {
                redirect(U('lists'));
            }
            if($button=='添加明细' || $button=='提交' || $button=='新增行程') {
                if($this->checkApplicationContent($content, $subtype) == false)
                    return false;
            }
            if($button=='提交') {
                if($this->checkIfItemAdded($application_id) == false)
                    return false;
            }

            if($button=='保存' || $button=='提交') {
                $update_data['is_del'] = false;
            }
            if($button=='取消' || $button=='刪除')
                $update_data['is_del'] = true;
            else {
                $update_data['content'] = json_encode($content, JSON_UNESCAPED_UNICODE);
            }
            if($this->saveApplication($application_id, $update_data) == false)
                return false;

            if($button == '提交') {
                if($this->submitApplication($application_id, $userInfo) == false)
                    return false;
            }
            if($button == '新增行程' || $button == '删除行程') {
                redirect(U('add', array('application_id'=>$application_id, 'type'=>3, 'subtype'=>0)));
            }
            if($button == '添加明细') {
                if(empty($itinerary_id))
                    $url = addons_url('OaSystem://OaApplyItem/add', array('application_id'=>$application_id));
                else
                    $url = addons_url('OaSystem://OaApplyItem/add', array('application_id'=>$application_id, 'itinerary_id'=>($itinerary_id-1)));
                redirect($url);
            }
            $this->success ( $button . $model ['title'] . '成功！', U ( 'lists?model=' . $model ['name'], $this->get_param ));
        } else {
            $type = $_GET['type'];
            $subtype = $_GET['subtype'];
            $application_id = $_GET['application_id'];
            if(empty($application_id)) {
                if(($application_id = $this->createNewApplication($type, $subtype, $userInfo)) == false)
                    return false;
            } else {
                $this->updateApplicationTotalmoney($application_id, $userInfo);
            }

            $applyInfo = $this->buildApplicationHtmlData($application_id, $userInfo);
            $post_url = addons_url('OaSystem://OaApplication/add', array('type'=>$type));
            $this->assign('applyInfo', $applyInfo);
            $this->assign('post_url', $post_url);
            $this->display('applyForm');
        }
    }

    public function approveApplication(){
        if(IS_POST) {
            $application_id = $_POST['application_id'];
            $comment = $_POST['comment'];
            $data = $this->getApplication($application_id);

            if($_POST['button_reject']==1) {
                $ret = process_reimburse_apply($data, $data['step'], -1, $comment, $this->cur_emp_id, $this->appId, null,false);
                if(!empty($ret['errmsg'])) {
                    $this->error(__METHOD__.'['.__LINE__.']'.$ret['errmsg']);
                    return false;
                }
                else {
                    $this->success ( '驳回' . $model ['title'] . '成功！', U ( 'lists?model=' . $model ['name'], $this->get_param ));
                }
            } else if($_POST['button_pass']==1) {
                $curStep = $data['step'];
                $data['step'] += 1;
                $ret = process_reimburse_apply($data, $curStep, 1, $comment, $this->cur_emp_id, $this->appId, null,false);
                if(!empty($ret['errmsg'])) {
                    $this->error(__METHOD__.'['.__LINE__.']'.$ret['errmsg']);
                    return false;
                }
                else {
                    $this->success ( '审批通过' . $model ['title'] . '成功！', U ( 'takelists?model=' . $model ['name'], $this->get_param ));
                }
            }
        } else {
            $application_id = $_GET['application_id'];
            $type = $_GET['type'];
            $step = $_GET['step'];

            $data = $this->getApplication($application_id);

            if($data['approver'] != $this->cur_emp_id) { //take the application
                $data['approver'] = $this->cur_emp_id;
               $this->saveApplication($application_id, $data);
            }

            if(($applyerInfo =  $this->getUserInfo($data['applyer'])) == false) {
                $this->error(__METHOD__.'['.__LINE__.']'.'查找报销申请员工信息失败！');
                return false;
            }

            $applyDetails = $this->buildApplicationHtmlData($application_id, $applyerInfo);
            $post_url = addons_url('OaSystem://OaApplication/approveApplication', array('type'=>$type));
            $this->assign('applyInfo', $applyDetails);
            $this->assign('post_url', $post_url);
            $this->display('approveForm');
        }
    }

    public function details(){
        if(IS_POST) {

        } else {
            $application_id = $_GET['application_id'];
            $data = $this->getApplication($application_id);
            if(($applyerInfo =  $this->getUserInfo($data['applyer'])) == false) {
                $this->error(__METHOD__.'['.__LINE__.']'.'查找报销申请员工信息失败！');
                return false;
            }
            $applyDetails = $this->buildApplicationHtmlData($application_id, $applyerInfo);
            $this->assign('applyInfo', $applyDetails);
            $this->display('details');
        }
    }

    public function print_details(){
        if(IS_POST) {
            $application_id = $_POST['application_id'];
            $button = $_POST['button'];
            if($button == '保存') {
                $data = $this->getApplication($application_id);
                $content = json_decode($data['content'], true);
                $content['payOrder'] = $_POST['payOrder'];
                $content['pay']['card'] = floatval($_POST['paycard']);
                $content['pay']['transfer'] = floatval($_POST['paytransfer']);
                $content['pay']['cash'] = floatval($_POST['paycash']);
                $data['content'] = json_encode($content, JSON_UNESCAPED_UNICODE);
                if($this->saveApplication($application_id, $data))
                    $this->success ( '保存' . $model ['title'] . '成功！', U('print_details', array('application_id'=>$application_id)));
            }
        } else {
            $application_id = $_GET['application_id'];
            $data = $this->getApplication($application_id);
            if(($applyerInfo =  $this->getUserInfo($data['applyer'])) == false) {
                $this->error(__METHOD__.'['.__LINE__.']'.'查找报销申请员工信息失败！');
                return false;
            }
            $printDetails = $this->buildApplicationPrintDetails($application_id, $applyerInfo);
            $this->assign('applyPrint', $printDetails);
            $this->display();
        }
    }

    public function applicationDone(){
        if(IS_POST) {
            $application_id = $_POST['application_id'];
            $comment = $_POST['comment'];
            $data = $this->getApplication($application_id);

            if($_POST['button_done']==1) {
                $ret = appliction_done($application_id, $comment, $this->cur_emp_id, $this->appId, null, false);
                if(!empty($ret['errmsg'])) {
                    $this->error(__METHOD__.'['.__LINE__.']'.$ret['errmsg']);
                    return false;
                }
                else {
                    $this->success ( '审核完成' . $model ['title'] . '成功！', U ( 'takelists?model=' . $model ['name'], $this->get_param ));
                }
            }
        } else {
            $application_id = $_GET['application_id'];
            $type = $_GET['type'];
            $step = $_GET['step'];

            $data = $this->getApplication($application_id);

            if($data['approver'] != $this->cur_emp_id) { //take the application
                $data['approver'] = $this->cur_emp_id;
                $this->saveApplication($application_id, $data);
            }

            if(($applyerInfo =  $this->getUserInfo($data['applyer'])) == false) {
                $this->error(__METHOD__.'['.__LINE__.']'.'查找报销申请员工信息失败！');
                return false;
            }

            $applyDetails = $this->buildApplicationHtmlData($application_id, $applyerInfo);
            $applyDetails['last_step'] = $this->isApplicationLastStep($application_id);
            $post_url = addons_url('OaSystem://OaApplication/applicationDone');
            $this->assign('applyInfo', $applyDetails);
            $this->assign('post_url', $post_url);
            $this->display('approveForm');
        }
    }


    public function applicationManage(){
        if(IS_POST) {
            if(!empty($_POST['applyer'])) $query['applyer'] = $_POST['applyer'];
            if(!empty($_POST['approver'])) $query['approver'] = $_POST['approver'];
            if(!empty($_POST['dept_id'])) $query['dept_id'] = $_POST['dept_id'];
            if(!empty($_POST['subtype'])) $query['subtype'] = $_POST['subtype']-1;

            if(!empty($_POST['button_del'])) {
                $application_id = $_POST['button_del'];
                $data['is_del'] = 1;
                $this->saveApplication($application_id, $data);
            }
            $p = empty(I('p')) ? 1 : I('p');
            $query = json_encode($query);
            $url = U('applicationManage', array('p'=>$p, 'query'=>$query));
            redirect($url);
        } else {
            $p = empty(I('p')) ? 1 : I('p');
            $query = json_decode($_GET['query'], true);
            $row = 20;
            if(!empty($query))
                $map = $query;
            $map['is_del'] = array('neq', 1);
            $map['type'] = 3;
            $len = D('OaApplicationView')->where($map)->count();
            $applies = D('OaApplicationView')->where($map)->order('submit_date desc')->page($p,$row)->select();
            for ($i=0; $i<count($applies); $i++) {
                $applies[$i]['submit_date'] = date('Y-m-d H:i:s',$applies[$i]['submit_date']);
                $applies[$i]['type_name'] = $this->subTypeStr[$applies[$i]['subtype']];
                $applies[$i]['show_state'] = $this->getApplicationProgressState($applies[$i]['id']);
                $applies[$i]['show_state_color'] = ($applies[$i]['show_state'] == '驳回') ? 'red' : '';
                $applies[$i]['last_step'] = $this->isApplicationLastStep($applies[$i]['id']);
            }
            if ($len > $row) {
                $page = new \Think\Page ( $len, $row );
                $page->setConfig ( 'theme', '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END% %HEADER%' );
                $list_data ['_page'] = $page->show ();
            }

            $employees = db_select('oa_employee', null, null, 'id, name');
            $depts = $this->getDepts();
            for($i = 0; $i < 3; $i++) {
                $subtypes[$i]['id'] = $i+1;
                $subtypes[$i]['name'] = $this->subTypeStr[$i];
            }
            array_unshift($employees, array('id'=>null, 'name'=>'无'));
            array_unshift($depts, array('id'=>null, 'name'=>'全部'));
            $applyers = $approvers = $employees;

            if(!empty($query)) {
                foreach ($applyers as $i => $v) {
                    if($v['id'] == $query['applyer'])
                        $applyers[$i]['selected'] = 'selected';
                }
                foreach ($approvers as $i => $v) {
                    if($v['id'] == $query['approver'])
                        $approvers[$i]['selected'] = 'selected';
                }
                foreach ($depts as $i => $v) {
                    if($v['id'] == $query['dept_id'])
                        $depts[$i]['selected'] = 'selected';
                }
                if(isset($query['subtype']))
                    $subtypes[$query['subtype']]['selected'] = 'selected';
            }
            array_unshift($subtypes, array('id'=>null, 'name'=>'全部'));

            $this->assign('_page',$list_data ['_page']);
            $this->assign('applyers',$applyers);
            $this->assign('approvers',$approvers);
            $this->assign('depts',$depts);
            $this->assign('subtypes',$subtypes);
            $this->assign('applies',$applies);
            $this->display('managelists');
        }
    }


    private function createNewApplication($type, $subtype, $userInfo) {
        $data['appid'] = $this->appId;
        $data['type'] = $type;
        $data['applyer'] = $userInfo['emp_id'];
        $data['approver'] = $userInfo['emp_id'];
        $data['dept_id'] = $userInfo['dept_id'];
        $data['applyer_lvl'] = $userInfo['adminLvl_id'];
        $data['step'] = 1;
        $data['is_read'] = false;
        $data['status'] = false;
        $data['is_del'] = true;
        $data['subtype'] = $subtype;
        $data['total_money'] = 0;
        if($subtype == 0) {
            $content['itinerary'][0]['id'] = 0;
            $content['itinerary'][0]['people_num'] = 1;
            $data['content'] = json_encode($content, JSON_UNESCAPED_UNICODE);
        }
        $apply = M('OaApplication')->add($data);
        if($apply == false) {
            $this->error(__METHOD__.'['.__LINE__.']'.'添加申请表失败！');
            return false;
        }

        if(($applyType = db_find('oa_apply_type', ['id'=>$type])) == NULL) {
            $this->error(__METHOD__.'['.__LINE__.']'.'找不到报销类型表！');
            return false;
        }

        $data['apply_no'] = generateApplyNo($applyType['sn'], $apply);
        $data['submit_date'] = NOW_TIME;
        if(db_save('OaApplication', ['id'=>$apply], $data) === false) {
            $this->error(__METHOD__.'['.__LINE__.']'.'保存申请表失败！');
            return false;
        }
        return $apply;
    }


    private function getApplication($id) {
        if(empty($id)){
            $this->error(__METHOD__.'['.__LINE__.']'.'传入 application ID 为空！');
            return false;
        }

        if(($data =db_find('OaApplication', ['id'=>$id]))== NULL) {
            $this->error(__METHOD__.'['.__LINE__.']'.'找不到对应的的申请表！');
            return false;
        }
        return $data;
    }

    private function saveApplication($id, $data) {
        if(empty($id)){
            $this->error(__METHOD__.'['.__LINE__.']'.'传入 application ID 为空！');
            return false;
        }

        if (db_save('oa_application', ['id'=>$id], $data) === false) {
            $this->error(__METHOD__ . '[' . __LINE__ . ']' . '保存申请表失败！');
            return false;
        }
        return true;
    }

    private function updateApplicationTotalmoney($id, $userInfo) {
        if(($data =db_find('OaApplication', ['id'=>$id, 'applyer'=>$userInfo['emp_id']]))== NULL) {
            $this->error(__METHOD__.'['.__LINE__.']'.'找不到该员工提交的申请表！');
            return false;
        }
        $map['application_id'] = $id;
        if($data['subtype'] == 0) {
            $content = json_decode($data['content'], true);
            $itineraryids = array_column($content['itinerary'], 'id');
            $map['itinerary_id'] = array('in', $itineraryids);
        }
        $applyItems = db_select('oa_apply_item', $map);
        if(!empty($applyItems)) {
            $data['total_money'] = 0;
            foreach ($applyItems as $item) {
                $data['total_money'] += $item['total'];
            }

            if(db_save('OaApplication', ['id'=>$id], $data) === false) {
                $this->error(__METHOD__.'['.__LINE__.']'.'保存申请表失败！');
                return false;
            }
        }
    }

    private function submitApplication($id, $userInfo) {
        if(($data =db_find('OaApplication', ['id'=>$id, 'applyer'=>$userInfo['emp_id']]))== NULL) {
            $this->error(__METHOD__.'['.__LINE__.']'.'找不到该员工提交的申请表！');
            return false;
        }

        if(($flows = db_select('oa_process_flow', ['type'=>$data['type']])) == NULL) {
            $this->error(__METHOD__.'['.__LINE__.']'.'找不到对应申请表类型的流程表！');
            return false;
        }

        foreach ($flows as $flow) {
            $flow_attr = json_decode($flow['attr'], true);
            if(($data['total_money'] > $flow_attr['money']['min']) &&
                ($data['total_money'] < $flow_attr['money']['max'] || $flow_attr['money']['max'] == -1)) {
                $data['flow_id'] = $flow['id'];
                break;
            }
        }
        if(empty($data['flow_id'])) {
            $this->error(__METHOD__.'['.__LINE__.']'.'根据总金额找不到对应的流程表！');
            return false;
        }

        $data['hops'] = 1;
        $data['step'] = 2;
        $ret = process_reimburse_apply($data, 1, 1, null, $userInfo['emp_id'], $this->appId, null, false);
        if(!empty($ret['errmsg'])) {
            $this->error(__METHOD__.'['.__LINE__.']'.$ret['errmsg']);
            return false;
        }
        return true;
    }

    private function isApplicationLastStep($application_id) {
        $apply = $this->getApplication($application_id);
        if(($process_flow = db_find('oa_process_flow', ['id'=>$apply['flow_id']])) == NULL) {
            //$this->error(__METHOD__.'['.__LINE__.']'.'找不到该员工申请表对应的流程表！');
            return false;
        }
        $operations = json_decode($process_flow['operations'], true);
        if($apply['step'] == count($operations))
            return true;
        else
            return false;
    }

    private function buildApplicationHtmlData($id, $userInfo) {
        if(($data =db_find('OaApplication', ['id'=>$id, 'applyer'=>$userInfo['emp_id']]))== NULL) {
            $this->error(__METHOD__.'['.__LINE__.']'.'找不到该员工提交的申请表！');
            return false;
        }

        $time = date('Y-m-d H:i:s', $data['submit_date']);
        $subtype = $data['subtype'];

        $content = json_decode($data['content'], true);
        $start_addr = empty($content['src'])?'西藏自治区-拉萨市-城关区':implode('-', $content['src']);
        $end_addr = empty($content['dst'])?'西藏自治区-拉萨市-城关区':implode('-', $content['dst']);
        $totalDays = round((strtotime($content['end'])-strtotime($content['start']))/3600/24) + 1;
        $details = array(
            'start_date' => empty($content['start'])?date('Y-m-d',NOW_TIME):$content['start'],
            'end_date' => empty($content['end'])?date('Y-m-d',NOW_TIME):$content['end'],
            'totalDays' => $totalDays,
            'start_addr' => $start_addr,
            'end_addr' => $end_addr
        );

        if($subtype == 1) {
            if(empty($content['trainType'])) {
                $details['traintype'][0]['id'] = '';
                $details['traintype'][0]['name'] = '';
                $details['traintype'][0]['selected'] = 'disabled selected';
            }
            foreach ($this->meetingTrainTypes as $i => $v) {
                $details['traintype'][$i+1]['id'] = $i + 1;
                $details['traintype'][$i+1]['name'] = $v;
                $details['traintype'][$i+1]['selected'] = ($i===$content['trainType']) ? 'selected' : '';
            }
            $details['attendance'] = $content['attendance'];
            if(!empty($content['trainType']))
                $details['trainTypeStr'] = $this->meetingTrainTypes[$content['trainType']];
        }

        $itemTypes_Str = ($subtype < count($this->applyItemTypeStr)) ? $this->applyItemTypeStr[$subtype] : '';
        $itemTypes = array();
        foreach ($itemTypes_Str as $i => $v) {
            $itemTypes[$i]['index'] = $i;
            $itemTypes[$i]['name'] = $v;
        }

        $applyItems = db_select('oa_apply_item', ['application_id'=>$id]);
        foreach ($applyItems as $i => $item) {
            $itemContent = json_decode($item['content'], true);
            $applyItems[$i]['invoiceCount'] = empty($itemContent['invoiceCount'])?0:$itemContent['invoiceCount'];
            if(!empty($itemContent['qty'])) $applyItems[$i]['quantity'] = $itemContent['qty'];
            if(!empty($itemContent['price'])) $applyItems[$i]['price'] = $itemContent['price'];
            if(!empty($itemContent['standard'])) $applyItems[$i]['standard'] = $itemContent['standard'];
            if(!empty($itemContent['fileCount'])) $applyItems[$i]['fileCount'] = $itemContent['fileCount'];
            if(!empty($itemContent['files'])) {
                $files = json_decode($itemContent['files'], true);
                for($j = 0; $j < count($files); $j++){
                    $applyItems[$i]['files'][$j]['name'] = $files[$j]['name'];
                    $applyItems[$i]['files'][$j]['url'] = SITE_URL.$files[$j]['url'];
                }
            }
            $itemPictures_url = json_decode($item['pictures'], true);
            foreach($itemPictures_url as $j => $picUrl) {
                $itemPictures_url[$j] = SITE_URL.$picUrl;
            }
            $applyItems[$i]['pictures'] = $itemPictures_url;
        }

        if($subtype == 0) {
            $itinerarys = array();
            foreach ($content['itinerary'] as $i => $v) {
                $itinerarys[$i]['id'] = $v['id'] + 1;
                $itinerarys[$i]['start_date'] = empty($v['start'])?date('Y-m-d',NOW_TIME):$v['start'];
                $itinerarys[$i]['end_date'] = empty($v['end'])?date('Y-m-d',NOW_TIME):$v['end'];
                $itinerarys[$i]['start_addr'] = empty($v['src'])?'西藏自治区-拉萨市-城关区':implode('-',$v['src']);
                $itinerarys[$i]['end_addr'] = empty($v['dst'])?'西藏自治区-拉萨市-城关区':implode('-',$v['dst']);
                $itinerarys[$i]['days'] = empty($v['days'])?1:$v['days'];
                $itinerarys[$i]['people_num'] = empty($v['people_num'])?1:$v['people_num'];
                $itinerarys[$i]['items'] = array();
                foreach ($applyItems as $item) {
                    if(isset($item['itinerary_id']) && $item['itinerary_id'] == $v['id'])
                        array_push($itinerarys[$i]['items'], $item);
                }
            }
        }

        //meeting total money hint
        if($subtype == 1 && !empty($applyItems)) {
            $total_except_tuition = 0;
            foreach ($applyItems as $item) {
                if($item['type'] != '授课费' && $item['type'] != '备注费用')
                    $total_except_tuition += $item['total'];
            }
            $days = round((strtotime($content['end'])-strtotime($content['start']))/86400)+1;
            $people_num = $content['attendance'];
            $meeting_std = db_find('oa_meeting_reimburse_standard');
            $meeting_std_person_daily = json_decode($meeting_std['total'], true)[$content['trainType']];
             if($days > 30)
                $meeting_std_total = $meeting_std_person_daily*$people_num*30 + $meeting_std_person_daily*$people_num*(30-$days)*0.7;
            else
                $meeting_std_total = $meeting_std_person_daily*$people_num*$days;
            if($total_except_tuition > $meeting_std_total) {
                $meeting_std_total_hint = '[提示] '.$content['trainTypes'][$content['trainType']];
                $meeting_std_total_hint .= '培训标准是每人/天不超过'.$meeting_std_person_daily.'元, ';
                $meeting_std_total_hint .= '当前除授课费外总额是'.$total_except_tuition.'元, ';
                $meeting_std_total_hint .= '按标准除授课费外总额不超过'.'<font style="font-weight:bold">'.$meeting_std_total.'</font>'.'元!';
            }
        }

        $processBar = array();
        $flow = db_find('oa_process_flow', ['id'=>$data['flow_id']]);
        $operations = json_decode($flow['operations'], true);
        $stepNum = count($operations);
        foreach ($operations as $i => $node_id) {
            $node = db_find('oa_node', ['id'=>$node_id]);
            $processBar[$i]['nodeName'] = $node['name'];
            $processBar[$i]['step'] = $i;
        }
        for ($step = $data['step']; $step >= 1; $step--) {
            $logs = db_select('oa_process_log', ['application_id'=>$id, 'step'=>$step], 'time desc');
            $applyerName = $this->getUserInfo($logs[0]['emp_id'])['name'];
            $nodePersonName = ($step==1) ? $applyerName : $logs[0]['approver_name'];
            if($step == 1)
                $description = ' 提交申请';
            else if(($step < $data['step']) || ($data['status'] == true))
                $description = ' 审核完成';
            else
                $description = ' 处理中...';
            /*
            if(!empty($logs) && $logs[0]['result']==0 ) {
                $description = ' 驳回';
                $processBar[$step-1]['comment'] = '[意见: '.$logs[0]['comment'].']';
            }
            */
            $processBar[$step-1]['nodeState'] = $nodePersonName.$description;
        }
        for($step = $data['step']; $step <= $stepNum; $step++) {
            $processBar[$step-1]['active'] = 'active';
        }
        $processBar[$stepNum-1]['last_step'] = true;

        $failback = $this->checkIfApplicationFailback($id);

         $applyInfo = array(
            'id'   =>  $data['id'],
            'applyer' => $userInfo['name'],
            'dept'  => $userInfo['dept'],
            'duty'  => $userInfo['duty'],
            'type' => $this->subTypeStr[$subtype],
            'create_time'=> $time,
            'apply_no' => $data['apply_no'],
            'subtype' => $subtype,
            'total_money' => $data['total_money'],
            'itemTypes' =>$itemTypes,
            'items' => $applyItems,
            'details' => $details,
            'process_bar' => $processBar,
            'is_draft' => ($data['is_del']==0)?1:null,
            'failback' => $failback,
            'meeting_std_total_hint' => $meeting_std_total_hint,
            'itinerarys' => $itinerarys,
            'costCenter' => $content['costCenter'],
            'project' => $content['project']
        );
        return $applyInfo;
    }

    private function buildApplicationPrintDetails($id, $userInfo) {
        if(($data =db_find('OaApplication', ['id'=>$id, 'applyer'=>$userInfo['emp_id']]))== NULL) {
            $this->error(__METHOD__.'['.__LINE__.']'.'找不到该员工提交的申请表！');
            return false;
        }

        $subtype = $data['subtype'];
        $content = json_decode($data['content'], true);
        $applyItems = db_select('oa_apply_item', ['application_id'=>$id]);

        $printInfo = array();
        $printInfo['id'] = $id;
        $printInfo['apply_no'] = $data['apply_no'];
        $printInfo['applyer'] = $userInfo['name'];
        $printInfo['dept'] = $userInfo['dept'];
        $printInfo['duty'] = $userInfo['duty'];
        $printInfo['subtype'] = $subtype;
        $printInfo['subtypeStr'] = $this->subTypeStr[$subtype];
        $printInfo['date'] = date('Y 年 m 月 d 日', time());
        $printInfo['costCenter'] = $content['costCenter'];
        $printInfo['project'] = $content['project'];
        $printInfo['payOrder'] = $content['payOrder'];
        $printInfo['pay']['card'] = $content['pay']['card'];
        $printInfo['pay']['transfer'] = $content['pay']['transfer'];
        $printInfo['pay']['cash'] = $content['pay']['cash'];
        $printInfo['total_money'] = floatval($data['total_money']);
        $printInfo['total_money_cn'] = $this->num_to_rmb($data['total_money']);
        $printInfo['invoiceCount']  = 0;
        foreach ($applyItems as $v) {
            $itemContent = json_decode($v['content'], true);
            $printInfo['invoiceCount'] += $itemContent['invoiceCount'];
        }
        $printInfo['items'] = array();
        if($subtype == 0) {
            foreach ($content['itinerary'] as $v) {
                $item = array();
                $item['start'] = date('y-m-d', strtotime($v['start']));
                $item['end'] = date('y-m-d', strtotime($v['end']));
                $item['src'] = $v['src'][1];
                $item['dst'] = $v['dst'][1];
                $item['days'] = $v['days'];
                $item['people_num'] = $v['people_num'];
                foreach ($applyItems as $k) {
                    if(!isset($k['itinerary_id']) ||
                        ($k['itinerary_id'] != $v['id'])) {
                        continue;
                    }
                    $itemTotal = floatval($k['total']);
                    $itemContent = json_decode($k['content'], true);
                    switch ($k['type']) {
                        case '交通费':
                            $item['transport'] = $itemTotal;
                            $printInfo['transport_total'] += $itemTotal;
                            break;
                        case '住宿费':
                            $item['hotel'] = $itemTotal;
                            $printInfo['hotel_total'] += $itemTotal;
                            break;
                        case '培训费':
                            $item['train'] = $itemTotal;
                            $printInfo['train_total'] += $itemTotal;
                            break;
                        case '其他':
                            $item['other'] = $itemTotal;
                            $printInfo['other_total'] += $itemTotal;
                            break;
                        case '伙食补助费':
                            $item['meals'] = $itemTotal;
                            $item['meals_std'] = $itemContent['standard_val'];
                            $printInfo['meals_total'] += $itemTotal;
                            break;
                        case '市内交通费':
                            $item['traffic'] = $itemTotal;
                            $item['traffic_std'] = $itemContent['standard_val'];
                            $printInfo['traffic_total'] += $itemTotal;
                            break;
                    }
                }
                array_push($printInfo['items'], $item);
            }
            if(count($printInfo['items']) < 6) {
                for ($i = count($printInfo['items']); $i < 6; $i++) {
                    $tmp['start'] = ' ';
                    array_push($printInfo['items'], $tmp);
                }
            }
        } else if($subtype == 1) {
            $meeting['start'] = date('y-m-d', strtotime($content['start']));
            $meeting['end'] = date('y-m-d', strtotime($content['end']));
            $meeting['dst'] = $content['dst'][1];
            $meeting['days'] = round((strtotime($content['end'])-strtotime($content['start']))/86400)+1;
            $meeting['people_num'] = $content['attendance'];
            $meeting['type'] = $content['trainTypes'][$content['trainType']];
            foreach ($applyItems as $it) {
                $itemTotal = floatval($it['total']);
                switch ($it['type']) {
                    case '住宿费':
                        $meeting['hotel'] += $itemTotal;
                        break;
                    case '伙食费':
                        $meeting['meals'] += $itemTotal;
                        break;
                    case '场地费':
                        $meeting['place'] += $itemTotal;
                        break;
                    case '授课费':
                        $meeting['train'] += $itemTotal;
                        break;
                    case '其他费用':
                        $meeting['other'] += $itemTotal;
                        break;
                    case '备注费用':
                        $meeting['note'] += $itemTotal;
                        break;
                }
            }
            $printInfo['meeting'] = $meeting;
        } else if($subtype == 2) {
            $printInfo['startend'] = date('y/m/d', strtotime($content['start'])).' - '.date('y/m/d', strtotime($content['end']));
            $printInfo['place'] = $content['dst'][1];
            $printInfo['description'] = $applyItems[0]['description'];
        }

        $processBar = array();
        $flow = db_find('oa_process_flow', ['id'=>$data['flow_id']]);
        $operations = json_decode($flow['operations'], true);
        foreach ($operations as $i => $node_id) {
            $node = db_find('oa_node', ['id'=>$node_id]);
            $processBar[$i]['nodeName'] = $node['name'];
            $processBar[$i]['step'] = $i;
        }
        for ($step = $data['step']; $step >= 1; $step--) {
            $logs = db_select('oa_process_log', ['application_id'=>$id, 'step'=>$step], 'time desc');
            $applyerName = $this->getUserInfo($logs[0]['emp_id'])['name'];
            $nodePersonName = ($step==1) ? $applyerName : $logs[0]['approver_name'];
            if($step == 1)
                $description = ' 提交申请';
            else if(($step < $data['step']) || ($data['status'] == true))
                $description = ' 审核完成';
            else
                $description = ' 处理中...';

            $processBar[$step-1]['nodeState'] = $nodePersonName.$description;
        }
        array_pop($processBar);

        $printInfo['process_bar'] = $processBar;
        return $printInfo;
    }

    /**
     *数字金额转换成中文大写金额的函数
     *String Int $num 要转换的小写数字或小写字符串
     *return 大写字母
     *小数位为两位
     **/
    private function num_to_rmb($num){
        $c1 = "零壹贰叁肆伍陆柒捌玖";
        $c2 = "分角元拾佰仟万拾佰仟亿";
        //精确到分后面就不要了，所以只留两个小数位
        $num = round($num, 2);
        //将数字转化为整数
        $num = $num * 100;
        if (strlen($num) > 10) {
            return "金额太大，请检查";
        }
        $i = 0;
        $c = "";
        while (1) {
            if ($i == 0) {
                //获取最后一位数字
                $n = substr($num, strlen($num)-1, 1);
            } else {
                $n = $num % 10;
            }
            //每次将最后一位数字转化为中文
            $p1 = substr($c1, 3 * $n, 3);
            $p2 = substr($c2, 3 * $i, 3);
            if ($n != '0' || ($n == '0' && ($p2 == '亿' || $p2 == '万' || $p2 == '元'))) {
                $c = $p1 . $p2 . $c;
            } else {
                $c = $p1 . $c;
            }
            $i = $i + 1;
            //去掉数字最后一位了
            $num = $num / 10;
            $num = (int)$num;
            //结束循环
            if ($num == 0) {
                break;
            }
        }
        $j = 0;
        $slen = strlen($c);
        while ($j < $slen) {
            //utf8一个汉字相当3个字符
            $m = substr($c, $j, 6);
            //处理数字中很多0的情况,每次循环去掉一个汉字“零”
            if ($m == '零元' || $m == '零万' || $m == '零亿' || $m == '零零') {
                $left = substr($c, 0, $j);
                $right = substr($c, $j + 3);
                $c = $left . $right;
                $j = $j-3;
                $slen = $slen-3;
            }
            $j = $j + 3;
        }
        //这个是为了去掉类似23.0中最后一个“零”字
        if (substr($c, strlen($c)-3, 3) == '零') {
            $c = substr($c, 0, strlen($c)-3);
        }
        //将处理的汉字加上“整”
        if (empty($c)) {
            return "零元整";
        }else{
            return $c . "整";
        }
    }

    private function getApplicationProgressState($application_id) {
        $data = $this->getApplication($application_id);
        $flow = db_find('oa_process_flow', ['id'=>$data['flow_id']]);
        $operations = json_decode($flow['operations']);
        $step = $data['step'];
        $stepNum = count($operations);
        $failback = $this->checkIfApplicationFailback($application_id);

        if($step == 1)
            $state = $failback ? '驳回' : '草稿';
        else if($step < $stepNum)
            $state = $failback ? '驳回' : '审批中';
        else if($data['status'] == true)
            $state = '已结案';
        else
            $state = '审批完成';

        return $state;
    }

    private function checkApplicationContent($content, $subtype) {
        if($subtype == 0) {
            if(empty($content['itinerary'])) {
                $this->error('没有添加任何行程！');
                return false;
            }
            foreach ($content['itinerary'] as $v) {
                if(strtotime($v['end']) < strtotime($v['start'])) {
                    $this->error('行程'.($v['id']+1).' 结束日期 要大于 起始日期，谢谢！');
                    return false;
                }
                if(!empty($pre_iti)) {
                    if(strtotime($v['start']) < strtotime($pre_iti['end'])) {
                        $this->error('行程'.($v['id']+1).' 起始日期 要大于等于 上个行程 结束日期，谢谢！');
                        return false;
                    }
                }
                $pre_iti = $v;
            }
        } else if($subtype == 1) {
            if((empty($content['start']) || empty($content['end']) || empty($content['dst']))) {
                $this->error('添加 明细 之前需要先选择日期和地点，谢谢！');
                return false;
            }
            if(strtotime($content['end']) < strtotime($content['start'])) {
                $this->error('结束日期 要大于 起始日期，谢谢！');
                return false;
            }
            if(!empty($content['trainTypes']) && !isset($content['trainType'])) {
                $this->error('请选择培训类型，谢谢！');
                return false;
            }
            if(!empty($content['trainTypes']) && empty($content['attendance'])) {
                $this->error('请输入与会人数，谢谢！');
                return false;
            }
        }

        return true;
    }

    private function checkIfItemAdded($application_id) {
        if(db_select('oa_apply_item', ['application_id'=>$application_id]) == NULL) {
            $this->error('该申请表还没有添加明细!');
            return false;
        }
        return true;
    }
    private function checkIfApplicationFailback($application_id) {
        $logs = db_select('oa_process_log', ['application_id'=>$application_id], 'time desc');
        $failback = (!empty($logs) && $logs[0]['result']==0) ? true : false;
        return $failback;
    }
}